﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;

namespace Edge.OAuth
{
    public static class OAuthCommonUtils
    {
        public static string GetTimestamp(int delta) //delta понадобится для указания разницы между временем нашего сервера и временем на сервере, к которому пойдут запросы - надо автоматизировать: написать метод, который будет это делать за нас
        {
            return ((int)((TimeSpan)(DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0))).TotalSeconds + delta).ToString();
        }

        public static void Redirect(string url)
        {
            HttpContext.Current.Response.Redirect(url, false);
        }

        public static string GetAuthHeader(Dictionary<string, string> items)
        {
            string result = string.Empty;
            result = string.Format("OAuth {0}", string.Join(", ", (string[]) items.Select(x => string.Format("{0}=\"{1}\"", x.Key, OAuthCommonUtils.UrlEncode(x.Value)))));
            return result;
        }



        public static string GetNonce()
        {
            Random rnd = new Random();
            int nonce = rnd.Next(1, Int32.MaxValue);
            MD5 md5 = MD5.Create(); //на всякий случай сделал md5-хеш хотя можно было просто сконвертить в base64
            byte[] b = md5.ComputeHash(Encoding.UTF8.GetBytes(nonce.ToString()));
            return string.Concat(b.Select(x => x.ToString("x2")));
        }
        static string unreservedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
        public static string UrlEncode(string value)
        {
            StringBuilder result = new StringBuilder();
            foreach (char symbol in value)
            {
                if (unreservedChars.IndexOf(symbol) != -1)
                    result.Append(symbol);
                else
                    result.AppendFormat("%{0:X2}", (int)symbol);
            }
            return result.ToString();
        }
        public static string GetBasesign(string method, string baseUrl, Dictionary<string, string> items)
        {
            string parameters = string.Join("%26", items.OrderBy(x => x.Key).Select(x => string.Format("{0}%3D{1}", UrlEncode(x.Key), UrlEncode(x.Value))) as string[]);
            return string.Format("{2}&{0}&{1}", UrlEncode(baseUrl), parameters, method);
        }
        public static string GetHMACSHA1(string key, string token_secret, string sourceStr)
        {
            UTF8Encoding encoding = new UTF8Encoding();
            string token_secret_encoded = string.Empty;
            if (!string.IsNullOrEmpty(token_secret))
                token_secret_encoded = UrlEncode(token_secret);
            HMACSHA1 hmacsha1 = new HMACSHA1(encoding.GetBytes(HttpUtility.UrlEncode(key) + "&" + token_secret_encoded));
            byte[] encoded = hmacsha1.ComputeHash(encoding.GetBytes(sourceStr));
            return Convert.ToBase64String(encoded);
        }
        public static string GetParametersString(Dictionary<string, string> items)
        {
            string str = "";
            foreach (var item in items)
            {
                str = string.Format("&{0}={1}", item.Key, item.Value)+str;
            }
            str = str.Substring(1);
            return string.Format("?{0}", str);
        }

        public static Dictionary<string, string> SendGetRequest(string url, bool IsExpect, string OAuthHeader)
        {
            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
            httpWebRequest.Method = "GET";

            if (IsExpect)
                httpWebRequest.ServicePoint.Expect100Continue = false;

            if (!string.IsNullOrEmpty(OAuthHeader))
                httpWebRequest.Headers.Add("Authorization", OAuthHeader);

            Dictionary<string, string> dict = new Dictionary<string, string>();
            try
            {
                HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                string response = string.Empty;
                using (StreamReader sr = new StreamReader(httpWebResponse.GetResponseStream()))
                    response = sr.ReadToEnd();
                string[] parameters = response.Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries);

                foreach (string item in parameters)
                {
                    string[] p = item.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                    dict.Add(p[0], HttpUtility.UrlDecode(p[1]));
                }
                dict.Add("raw_response", response);
            }
            catch (WebException e)
            {
                string excmsg = string.Empty;
                using (StreamReader sr = new StreamReader(e.Response.GetResponseStream()))
                {
                    excmsg = sr.ReadToEnd();
                }
                throw new WebException(excmsg);
            }
            return dict;
        }
        public static string SendPostRequest(string url, string parameters)
        {
            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
            httpWebRequest.Method = "POST";
            httpWebRequest.Accept = "*/*";
            httpWebRequest.AllowAutoRedirect = true;
            httpWebRequest.ContentType = "application/x-www-form-urlencoded";
            byte[] data = Encoding.UTF8.GetBytes(parameters);
            httpWebRequest.ContentLength = data.Length;
            httpWebRequest.GetRequestStream().Write(data, 0, data.Length);
            string raw_token = string.Empty;
            try
            {
                HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();

                using (StreamReader sr = new StreamReader(httpWebResponse.GetResponseStream()))
                {
                    raw_token = sr.ReadToEnd();
                }
            }
            catch (WebException e)
            {
                string exception = string.Empty;
                using (StreamReader sr = new StreamReader(e.Response.GetResponseStream()))
                {
                    exception = sr.ReadToEnd();
                }
                throw new WebException(exception);
            }
            return raw_token;
        }
        public static string GetPlainTextResponse(string url)
        {
            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
            httpWebRequest.Method = "GET";
            httpWebRequest.AllowAutoRedirect = true;
            string response = "";
            try
            {
                HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();

                using (StreamReader sr = new StreamReader(httpWebResponse.GetResponseStream()))
                {
                    response = sr.ReadToEnd();
                }
            }
            catch (WebException exc)
            {
                string excmsg = string.Empty;
                using (StreamReader sr = new StreamReader(exc.Response.GetResponseStream()))
                {
                    excmsg = sr.ReadToEnd();
                }
                throw new WebException(excmsg);
            }
            return response;
        }
    }
   
}
